package edu.buffalo.cse.cse486_586.activity;

import edu.buffalo.cse.cse486_586.R;
import edu.buffalo.cse.cse486_586.service.MessageBean;
import edu.buffalo.cse.cse486_586.service.NetWorkService;
import edu.buffalo.cse.cse486_586.util.AppUtil;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SlidingDrawer;

public class MainActivity extends Activity implements OnClickListener {
	// Debugging
	private static final String TAG = "CSE586_PRO0";
	private static final boolean D = true;

	// Layout Views
	//private TextView localIPTextView;
	private ListView msgList;
	private EditText msgTxt;
	private EditText ipTxt;
	private EditText portTxt;
	private Button testCase1;
	private Button testCase2;
	private Button sendButton;
	private Button cleanButton;

	// Array adapter for the conversation thread
	private ArrayAdapter<String> msgListAdapter;

	// incoming Messenger for communicating with service.
	final private Messenger incommingMessager = new Messenger(new MessagerHandler());
	// outgoing Messenger for communicating with service
	private Messenger outgoingMessager = null;
	// Flag indicating whether we have called bind on the service.
	boolean mIsBound;

	// Handler of messages from binded service.
	class MessagerHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			if (D)
				Log.d(TAG, "activity handle Message");
			switch (msg.what) {
			case AppUtil.MSG_RECEIVE:
				String totalOrder = msg.getData().getString(AppUtil.TOTOAL_ORDER, "127.0.0.1");
				String content = msg.getData().getString(AppUtil.CONTENT, "");
				
				ContentValues cv = new ContentValues();
		    	cv.put(AppUtil.MessageTable.COL_PROVIDER_KEY, totalOrder);
		    	cv.put(AppUtil.MessageTable.COL_PROVIDER_VALUE, content);
		    	getContentResolver().insert(AppUtil.CONTENT_URI, cv);
				
		    	msgListAdapter.clear();
		    	queryData();
				//msgListAdapter.add(ip + " : " + content);
				break;
			case AppUtil.MSG_SEND:
			default:
				super.handleMessage(msg);
			}
		}
	}

	/**
	 * Class for interacting with the main interface of the service.
	 */
	public NetWorkConnection mConnection = new NetWorkConnection();

	class NetWorkConnection implements ServiceConnection {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// This is called when the connection with the service has been
			// established, giving us the service object we can use to
			// interact with the service. We are communicating with our
			// service through an IDL interface, so get a client-side
			// representation of that from the raw service object.
			outgoingMessager = new Messenger(service);
			if (D)
				Log.d(TAG, "Attached.");

			// We want to monitor the service for as long as we are
			// connected to it.
			try {
				Message msg = Message.obtain(null, AppUtil.MSG_REGISTER_CLIENT);
				msg.replyTo = incommingMessager;
				outgoingMessager.send(msg);
			} catch (RemoteException e) {
				// In this case the service has crashed before we could even
				// do anything with it; we can count on soon being
				// disconnected (and then reconnected if it can be restarted)
				// so there is no need to do anything here.
			}
		}

		public void onServiceDisconnected(ComponentName className) {
			// This is called when the connection with the service has been
			// unexpectedly disconnected -- that is, its process crashed.
			outgoingMessager = null;
			if (D)
				Log.d(TAG, "detached.");
		}

		public void doSendMessage(String ip, String port, String msgContent) {
			try {
				Message msg = Message.obtain(null, AppUtil.MSG_SEND);
				android.os.Bundle b = new android.os.Bundle();
				b.putString(AppUtil.IP, ip);
				b.putString(AppUtil.SEND_PORT, port);
				b.putString(AppUtil.CONTENT, msgContent);
				msg.setData(b);
				msg.replyTo = incommingMessager;
				outgoingMessager.send(msg);
			} catch (RemoteException e) {
				// In this case the service has crashed before we could even
				// do anything with it; we can count on soon being
				// disconnected (and then reconnected if it can be restarted)
				// so there is no need to do anything here.
			}
		}
		
		public void testCase1(){
			try {
				Message msg = Message.obtain(null, AppUtil.TEST_CASE_1);
				outgoingMessager.send(msg);
			} catch (RemoteException e) {
				// In this case the service has crashed before we could even
				// do anything with it; we can count on soon being
				// disconnected (and then reconnected if it can be restarted)
				// so there is no need to do anything here.
			}
		}
		
		public void testCase2(){
			try {
				Message msg = Message.obtain(null, AppUtil.TEST_CASE_2);
				outgoingMessager.send(msg);
			} catch (RemoteException e) {
				// In this case the service has crashed before we could even
				// do anything with it; we can count on soon being
				// disconnected (and then reconnected if it can be restarted)
				// so there is no need to do anything here.
			}
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		setupChatView();
		// binding activity with service
		if (!mIsBound) {
			bindService(new Intent(this, NetWorkService.class), mConnection,
					Context.BIND_AUTO_CREATE);
			mIsBound = true;
		}
	}

	@Override
	public void onStart() {
		super.onStart();
	}

	/*
	 * set up UI interface once the activity start.
	 */
	private void setupChatView() {
		//localIPTextView = (TextView) findViewById(R.id.localAddr);
		//localIPTextView.setText(AppUtil.getAddressBySocket());
		// message view list
		msgList = (ListView) findViewById(R.id.msgList);
		msgListAdapter = new ArrayAdapter<String>(this, R.layout.list_msg);
		
		insertData();
		queryData();
		
		msgList.setAdapter(msgListAdapter);

		// ip && port Text
		ipTxt = (EditText) findViewById(R.id.ipTxt);
		portTxt = (EditText) findViewById(R.id.protTxt);
		// message Text
		msgTxt = (EditText) findViewById(R.id.msgTxt);
		// msgTxt.setOnEditorActionListener(msgTxtListener);
		// send button
		sendButton = (Button) findViewById(R.id.sendButton);
		testCase1 = (Button) findViewById(R.id.testCase1);
		testCase2 = (Button) findViewById(R.id.testCase2);
		sendButton.setOnClickListener(this);
		testCase1.setOnClickListener(new TestCase1Listener());
		testCase2.setOnClickListener(new TestCase2Listener());
		cleanButton = (Button) findViewById(R.id.CleanButton);
		cleanButton.setOnClickListener(new CPCleanListener());
	}

	@Override
	public void onClick(View v) {
		String message = msgTxt.getText().toString();
		String ip = ipTxt.getText().toString();
		String port = portTxt.getText().toString();
		Log.d(TAG, ip+"//"+port+"//"+message);
		mConnection.doSendMessage(ip, port, message);
	}
	
	private void insertData() {
    	ContentValues cv = new ContentValues();
    	cv.put(AppUtil.MessageTable.COL_PROVIDER_KEY, "msg0001");
    	cv.put(AppUtil.MessageTable.COL_PROVIDER_VALUE, "msg content 00001");
    	getContentResolver().insert(AppUtil.CONTENT_URI, cv);
    	
    	cv.put(AppUtil.MessageTable.COL_PROVIDER_KEY, "msg0002");
    	cv.put(AppUtil.MessageTable.COL_PROVIDER_VALUE, "msg content 00002");
    	getContentResolver().insert(AppUtil.CONTENT_URI, cv);
    }
    private void queryData() {
    	Cursor c = getContentResolver().query(AppUtil.CONTENT_URI, new String[] {
    		AppUtil.MessageTable.COL_ID,
    		AppUtil.MessageTable.COL_PROVIDER_KEY,
    		AppUtil.MessageTable.COL_PROVIDER_VALUE
    	}, null, null, null);
    	
    	if(c.moveToFirst()) {
    		while(!c.isAfterLast()) {
    			String out = "";
    			out += c.getString(c.getColumnIndexOrThrow(AppUtil.MessageTable.COL_PROVIDER_KEY));
    			out += "\n";
    			out += c.getString(c.getColumnIndexOrThrow(AppUtil.MessageTable.COL_PROVIDER_VALUE));
    			out += "\n\n";
    			msgListAdapter.add(out);
    			c.moveToNext();
    		}
    	}
    	
    }
    
    private void cleanContentProvide(){
    	getContentResolver().delete(AppUtil.CONTENT_URI, null, null);
    }
    
    private class TestCase1Listener implements OnClickListener{
		@Override
		public void onClick(View v) {
			mConnection.testCase1();
		}
    	
    }
    
    private class TestCase2Listener implements OnClickListener{
		@Override
		public void onClick(View v) {
			mConnection.testCase2();
		}
    }
    
    private class CPCleanListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			cleanContentProvide();
			msgListAdapter.clear();
		}
    }
}